﻿using MiniFox.Components;
using MiniFox.Log;

namespace MiniFox.Net
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TS"></typeparam>
    public abstract class WebAdapter<TS> : IWebAdapter<TS> where TS : Service
    {
        IAdapterSetting _setting;
        ILogger _logger;
        ServiceCollection<TS> _services;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="setting"></param>
        protected WebAdapter(IAdapterSetting setting)
        {
            _setting = setting;
        }
        /// <summary>
        /// 
        /// </summary>
        protected IServiceSettingCollection ServiceSettings
        {
            get { return _setting.ServiceSettings; } 
        }

        /// <summary>
        /// 
        /// </summary>
        public string Name
        {
            get
            {
                return _setting.Name;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public string Host
        {
            get
            {
                return _setting.Host;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public bool SSL
        {
            get
            {
                return _setting.SSL;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public int Port
        {
            get
            {
                return _setting.Port;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public virtual ILogger Logger
        {
            get
            {
                if (_logger == null)
                {
                    var loggerFactory = ComponentFactory.GetComponent<LoggerFactory>();
                    _logger = loggerFactory.CreateLogger(this._setting.Logger);
                }
                return _logger;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public abstract string FullHost { get; }
        /// <summary>
        /// 
        /// </summary>
        protected Type ServiceType
        {
            get
            {
                return Type.GetType(this._setting.ServiceType, false);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public ServiceCollection<TS> Services 
        {
            get
            {
                if (_services == null)
                    _services = new ServiceCollection<TS>();
                return _services;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public TS GetService(string name)
        {

            if (this.Services.Contains(name))
            {
                return this.Services[name];
            }
            IServiceSetting serviceSetting = this.ServiceSettings[name];
            TS service;
            if (this.ServiceType != null && typeof(TS).IsAssignableFrom(this.ServiceType))
                service = Activator.CreateInstance(this.ServiceType, serviceSetting, this) as TS;
            else
                service = this.CreateDefaultService(serviceSetting);
            this.Services.Add(service);
            return service;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceSetting"></param>
        /// <returns></returns>
        protected abstract TS CreateDefaultService(IServiceSetting serviceSetting);
    }
}
